home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / RTF / textflow.h < prev    next >
C/C++ Source or Header  |  1994-08-01  |  5KB  |  165 lines

  1. /* $Header: /usr/people/pcd/Src/RTF/RCS/textflow.h,v 1.1 92/11/23 12:58:52 pcd Exp Locker: pcd $
  2.  */
  3.  
  4. #ifndef __textflow_h
  5. #define __textflow_h
  6.  
  7. #include "space.h"
  8.  
  9. typedef unsigned char Byte;
  10. typedef long          Qty;
  11. /*
  12.  * A flow of text is a contiguous array of bytes.
  13.  * No restrictions are placed on the contents of the bytes,
  14.  * or the number of bytes that determine a character glyph.
  15.  * i.e. a flow of text is a superset of the C string
  16.  * conventions.
  17.  */
  18.  
  19.  
  20. class Node{
  21.   /*
  22.    * These are Nodes in a nary tree.
  23.    * The tree is always at least two levels deep,
  24.    * and n->parent() == n iff n is the root.
  25.    */
  26.  
  27. public:
  28.   const Node* parent() const      { return parent_; };
  29.   Node*       left() const        { return left_; };
  30.   Node*       right() const       { return right_; };
  31.  
  32. protected:
  33.   Node(Node* parent);
  34.   /* USE : assert(parent != 0);
  35.    *       Node(parent);
  36.    ******/
  37.   Node(Node* parent, Node* left_sibling, Node* right_child);
  38.   /* USE : if(left_sibling){
  39.    *         assert(parent == left_sibling->parent());
  40.    *         for(Node* x = left->sibling->right(); x; x=x->right())
  41.    *           if(x == right_child)
  42.    *             break;
  43.    *         assert(x == right_child);
  44.    *       }
  45.    *       if(right_sibling)
  46.    *         assert(right_sibling->parent() == parent);
  47.    *       n = new Node(parent, left_sibling, right_child);
  48.    *       assert(n->parent() == parent);
  49.    *       assert(n->left() == left_sibling);
  50.    *       assert(n->right_child() == right_child);
  51.    *       assert(left_sibling || parent->left_child() == n);
  52.    ******/
  53.  
  54.   ~Node();
  55.  
  56.   void   connect(Node*, Node*);
  57.   void   consume(Node*);
  58.   void   disconnect();
  59.  
  60.   Node*  left_child() const  { return left_child_; };
  61.   Node*  right_child() const { return right_child_; };
  62.  
  63. private:
  64.   Node* parent_; // can't be 0
  65.   Node* left_;
  66.   Node* right_;
  67.   Node* left_child_; // zero only for leaves
  68.   Node* right_child_;
  69. };
  70.  
  71.  
  72. class TextFlow: public Node{
  73.   /******
  74.    *
  75.    * A TextFlow treats a TextFlow as a flow of structured text.
  76.    * and n->left_child() == 0 iff n->right_child() == 0 iff n is a leaf,
  77.    *
  78.    ******/
  79.  
  80. public:
  81.   /*******/
  82.   TextFlow(const Byte* data, Qty siz);
  83.   /* USE : assert(qty > 0;
  84.    *       assert(data[siz-1] = 1); // i.e. can write to data[siz-1] NOTATION
  85.    *       textflow = new TextFlow(data, siz);
  86.    *******/
  87.  
  88.   ~TextFlow();
  89.  
  90.   Qty bytes() const                   { return bytes_; };
  91.   const Byte* data() const
  92.     { return data_; };
  93.  
  94.   Qty bytes_before() const;
  95.   Qty bytes_after() const;
  96.  
  97.   /****************/
  98.   const TextFlow* subflow(TextPosition first, TextPosition last) const;
  99.   /* DESC: get a substructure from the flow
  100.    * USE : assert(first <= last);
  101.    *       tf = textflow->subflow(first, last);
  102.    ****************/
  103.  
  104.   const TextFlow* leaf(TextPosition, TextPosition& move) const;
  105.   /*@#
  106.    *******************/
  107.  
  108.   /*******/
  109.   Qty read(Byte* dest, TextPosition first, TextPosition last) const;
  110.   /* DESC: retrieve bytes from a textflow
  111.    * USE : textflow = new TextFlow(data, qty)
  112.    *       assert(first <= last);
  113.    *       assert(first == last || dest[last-first-1] = 1);
  114.    *       qty = textflow->read(dest, first, last);
  115.    *       assert(qty <= last - first);
  116.    *       assert(IMPLIES(first < qty,
  117.    *            memcmp(data+first, dest, min(qty-first, last-first)) ));
  118.    *******/
  119.  
  120.   /**************/
  121.   virtual void line_shape(TextPosition, Extent& shape) const;
  122.   /*@#
  123.    **************/
  124.   
  125.   /**************/
  126.   virtual Qty character_shape(TextPosition first, Qty q,
  127.               Extent, Extent& used, int) const;
  128.   /* USE : assert(first <= last);
  129.    *       qty = textflow->character_shape(first, q, avail, used, w);
  130.    *       assert(qty <= last - first);
  131.    *       assert(qty == 0 || used < avail); //@# Extent::operator<
  132.    **************/
  133.  
  134.   /**********/
  135.   virtual void render(TextPosition, Qty, Point) const;
  136.   /* DESC: default behavior inherits from parent.
  137.    *       subclasses should draw the text.
  138.    ***********/
  139.  
  140.   TextFlow* parent() const
  141.     { return (TextFlow*)Node::parent(); };
  142.  
  143.   virtual void parse()
  144.     { };
  145.  
  146. protected:
  147.   TextFlow(TextFlow& parent, TextFlow* left, const Byte*, Qty);
  148.   TextFlow(TextFlow&, Qty, Qty);
  149.  
  150.   /* relatives of TextFlows are known to be TextFlows */
  151.   TextFlow*       left() const        { return (TextFlow*)Node::left(); };
  152.   TextFlow*       right() const       { return (TextFlow*)Node::right(); };
  153.   TextFlow*  left_child() const  { return (TextFlow*)Node::left_child(); };
  154.   TextFlow*  right_child() const { return (TextFlow*)Node::right_child(); };
  155.  
  156. private:
  157.   TextFlow* start_branch(Qty);
  158.   TextFlow* end_branch(Qty);
  159.  
  160.   Byte* data_;
  161.   Qty bytes_; 
  162. };
  163.  
  164. #endif
  165.